/*********************************************************************************************************************
 * COPYRIGHT NOTICE
 * Copyright (c) 2018,逐飞科技
 * All rights reserved.
 * 技术讨论QQ群：		一群：179029047(已满)
 *					二群：244861897(已满)
 *					三群：824575535
 *
 * 以下所有内容版权均属逐飞科技所有，未经允许不得用于商业用途，
 * 欢迎各位使用并传播本程序，修改内容时必须保留逐飞科技的版权声明。
 *
 * @file			seekfree_sht31.c
 * @company			成都逐飞科技有限公司
 * @author			逐飞科技(QQ3184284598)
 * @version			查看doc内version文件 版本说明
 * @Software		IAR 8.3 or MDK 5.24
 * @Taobao			https://seekfree.taobao.com/
 * @date			2020-03-25
 * @note			本文件作为IOT开发板 seekfree_sht31 传感器 API
 ********************************************************************************************************************/
#include "seekfree_sht31.h"
#include "zf_utick.h"

static float sht31_temp;
static float sht31_humidity;

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 写 IIC 总线命令
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	@param		cmd				CMD 命令
//	Sample usage:				sht31_write_cmd(FLEX_COMM0, SHT31_SOFTRESET);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void sht31_write_cmd (iot_flexcomm_index_list Index, uint16_t cmd)
#else
void sht31_write_cmd (flexcomm_index_list Index, uint16_t cmd)
#endif
{
	uint8_t data_buffer[2] = {(cmd >> 8)&0xFF, cmd&0xFF};
	I2C_MasterStart(iic_index[Index], SHT31_DEFAULT_ADDR, kI2C_Write);
	I2C_MasterWriteBlocking(iic_index[Index], data_buffer, 2, kI2C_TransferDefaultFlag);
	I2C_MasterStop(iic_index[Index]);
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 软件复位
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	Sample usage:				sht31_reset(FLEX_COMM0);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void sht31_reset (iot_flexcomm_index_list Index)
#else
void sht31_reset (flexcomm_index_list Index)
#endif
{
	sht31_write_cmd(Index, SHT31_SOFTRESET);
	delay_us(10);
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 软件初始化
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	Sample usage:				sht31_init(FLEX_COMM0);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void sht31_init (iot_flexcomm_index_list Index)
#else
void sht31_init (flexcomm_index_list Index)
#endif
{
	i2c_master_config_t iic_sht31_config;														// 定义一个 Flex COMM 配置结构体
	// 初始化 MPU6050 FlexCOMM 接口部分
	zf_iic_master_get_default_config( &iic_sht31_config);										// 获取默认设置
#ifdef IOT_BOARD
	iot_flexcomm_init(Index, FLEX_COMM_IIC_MASTER, &iic_sht31_config);
#else
	zf_flexcomm_init((flexcomm_index_list)Index, FLEX_COMM_IIC_MASTER, &iic_sht31_config);
#endif

	sht31_reset(Index);
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 读取设备状态
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	@return		uint16_t		16bit 状态码
//	Sample usage:				sht31_read_status(FLEX_COMM0);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
uint16_t sht31_read_status (iot_flexcomm_index_list Index)
#else
uint16_t sht31_read_status (flexcomm_index_list Index)
#endif
{
	uint8_t read_sht_buffer [2];
	uint16_t read_status;

	sht31_write_cmd(Index, SHT31_READSTATUS);
	I2C_MasterStart(iic_index[Index], SHT31_DEFAULT_ADDR, kI2C_Read);
	I2C_MasterReadBlocking(iic_index[Index], read_sht_buffer, 2, kI2C_TransferDefaultFlag);
	I2C_MasterStop(iic_index[Index]);

	read_status |= ((uint16_t)read_sht_buffer[0] << 8) & 0xFF00;
	read_status |= ((uint16_t)read_sht_buffer[1]) & 0x00FF;
	return read_status;
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 温度补偿
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	@param		enable			使能与否
//	Sample usage:				sht31_heater(FLEX_COMM0, true);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
void sht31_heater (iot_flexcomm_index_list Index, bool enable)
#else
void sht31_heater (flexcomm_index_list Index, bool enable)
#endif
{
	if (enable)
		sht31_write_cmd(Index, SHT31_HEATEREN);
	else
		sht31_write_cmd(Index, SHT31_HEATERDIS);
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 CRC-8 校验
//	@param		data			校验数据指针
//	@param		len				数据长度
//	@return		uint8_t			8bit CRC校验结果
//	Sample usage:				sht31_crc8(data, len);
//-------------------------------------------------------------------------------------------------------------------
uint8_t sht31_crc8 (const uint8_t *data, uint8_t len)
{
	const uint8_t POLYNOMIAL = 0x31;
	uint8_t crc = 0xFF;

	for (int j = len; j; --j)
	{
		crc ^= *data++;
		for (int i = 8; i; --i)
		{
			crc = ((crc & 0x80) ? (crc << 1) ^ POLYNOMIAL : (crc << 1));
		}
	}
	return crc;
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 读取数据
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	@return		bool			读取是否成功
//	Sample usage:				sht31_read_temp_hum(FLEX_COMM0);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
bool sht31_read_temp_hum (iot_flexcomm_index_list Index)
#else
bool sht31_read_temp_hum (flexcomm_index_list Index)
#endif
{
	uint8_t read_buffer[8];
	uint16_t ST, SRH;

	sht31_write_cmd(Index, SHT31_MEAS_HIGHREP);
	delay_ms(50);
	I2C_MasterStart(iic_index[Index], SHT31_DEFAULT_ADDR, kI2C_Read);
	I2C_MasterReadBlocking(iic_index[Index], read_buffer, 6, kI2C_TransferDefaultFlag);
	I2C_MasterStop(iic_index[Index]);

	ST = read_buffer[0];
	ST <<= 8;
	ST |= read_buffer[1];

	if (read_buffer[2] != sht31_crc8(read_buffer, 2)) return false;

	SRH = read_buffer[3];
	SRH <<= 8;
	SRH |= read_buffer[4];

	if (read_buffer[5] != sht31_crc8(read_buffer+3, 2)) return false;

	// Serial.print("ST = "); Serial.println(ST);
	double stemp = ST;
	stemp *= 175;
	stemp /= 0xffff;
	stemp = -45 + stemp;
	sht31_temp = stemp;

	//  Serial.print("SRH = "); Serial.println(SRH);
	double shum = SRH;
	shum *= 100;
	shum /= 0xFFFF;

	sht31_humidity = shum;

	return true;
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 读取当前温度
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	@return		float			浮点数温度值
//	Sample usage:				sht31_read_temperature(FLEX_COMM0);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
float sht31_read_temperature (iot_flexcomm_index_list Index)
#else
float sht31_read_temperature (flexcomm_index_list Index)
#endif
{
	if (sht31_read_temp_hum(Index))
		return sht31_temp;
	else
		return 0.0;
}

//-------------------------------------------------------------------------------------------------------------------
//	@brief		SHT31 读取当前湿度
//	@param		Index	Flex模块号( FC0, FC1, FC2, FC3, FC4, FC5, FC6, FC7 )
//	@return		float			浮点数湿度值
//	Sample usage:				sht31_read_humidity(FLEX_COMM0);
//-------------------------------------------------------------------------------------------------------------------
#ifdef IOT_BOARD
float sht31_read_humidity (iot_flexcomm_index_list Index)
#else
float sht31_read_humidity (flexcomm_index_list Index)
#endif
{
	if (sht31_read_temp_hum(Index))
		return sht31_humidity;
	else
		return 0.0;
}
